package com.web.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Random;

public class FileUtils
{
  private static final File POOL_FILE = getUniqueFile(FileUtils.class, ".deletefiles");
  private static ArrayList deleteFilesPool;

  private static void initPool()
  {
    if ((POOL_FILE.exists()) && (POOL_FILE.canRead()))
      try {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(POOL_FILE));

        deleteFilesPool = (ArrayList)in.readObject();
        in.close();
      } catch (Exception e) {
        deleteFilesPool = new ArrayList();
      }
    else
      deleteFilesPool = new ArrayList();
  }

  public static void copyFile(String fromFile, String toFile)
    throws IOException
  {
    FileInputStream in = new FileInputStream(fromFile);
    FileOutputStream out = new FileOutputStream(toFile);
    byte[] b = new byte[1024];
    int len;
    while ((len = in.read(b)) != -1) {
      out.write(b, 0, len);
    }
    out.close();
    in.close();
  }

  public static String getShortFileName(String fileName)
  {
    String shortFileName = "";
    int pos = fileName.lastIndexOf('\\');
    if (pos == -1) {
      pos = fileName.lastIndexOf('/');
    }
    if (pos > -1)
      shortFileName = fileName.substring(pos + 1);
    else {
      shortFileName = fileName;
    }
    return shortFileName;
  }

  public static String read(String fileName)
    throws Exception
  {
    String fileContent = "";
    fileContent = read(new FileInputStream(fileName));
    return fileContent;
  }

  public static String read(File file)
    throws Exception
  {
    String fileContent = "";
    fileContent = read(new FileInputStream(file));
    return fileContent;
  }

  public static String read(InputStream is)
    throws Exception
  {
    byte[] result = readBytes(is);
    return new String(result);
  }

  public static byte[] readBytes(String fileName)
    throws Exception
  {
    return readBytes(new FileInputStream(fileName));
  }

  public static byte[] readBytes(File file)
    throws Exception
  {
    return readBytes(new FileInputStream(file));
  }

  public static byte[] readBytes(InputStream is)
    throws Exception
  {
    if ((is == null) || (is.available() < 1)) {
      return new byte[0];
    }
    byte[] buff = new byte[8192];
    byte[] result = new byte[is.available()];

    BufferedInputStream in = new BufferedInputStream(is);
    int pos = 0;
    int nch;
    while ((nch = in.read(buff, 0, buff.length)) != -1) {
      System.arraycopy(buff, 0, result, pos, nch);
      pos += nch;
    }
    in.close();
    return result;
  }

  public static void write(String content, File file)
    throws IOException
  {
    write(content.getBytes(), file);
  }

  public static void write(String content, String file)
    throws IOException
  {
    write(content, new File(file));
  }

  public static void write(byte[] bytes, String file)
    throws IOException
  {
    write(bytes, new File(file));
  }

  public static void write(byte[] bytes, File file)
    throws IOException
  {
    FileOutputStream out = new FileOutputStream(file);
    out.write(bytes);
    out.flush();
    out.close();
  }

  public static String getFileNameWithoutExt(String fileName)
  {
    String shortFileName = fileName;
    if (fileName.indexOf('.') > -1) {
      shortFileName = fileName.substring(0, fileName.lastIndexOf('.'));
    }
    return shortFileName;
  }

  public static String getFileNameExt(String fileName)
  {
    String fileExt = "";
    if (fileName.indexOf('.') > -1) {
      fileExt = fileName.substring(fileName.lastIndexOf('.'));
    }
    return fileExt;
  }

  public static synchronized File getUniqueFile(File repository, String fileName)
  {
    String shortFileName = getShortFileName(fileName);
    String tempFileName = getFileNameWithoutExt(shortFileName);
    File file = new File(repository, shortFileName);
    String fileExt = getFileNameExt(shortFileName);
    while (file.exists()) {
      file = new File(repository, tempFileName + "-" + Math.abs(new Random().nextInt()) + fileExt);
    }

    return file;
  }

  public static void deleteFile(String fileName)
  {
    File file = new File(fileName);
    if (file.exists())
      deleteFile(file);
  }

  public static void deleteFile(File file)
  {
    file.delete();
    if (file.exists()) {
      deleteFilesPool.add(file);
    }
    checkDeletePool();
  }

  private static void checkDeletePool()
  {
    for (int i = deleteFilesPool.size() - 1; i >= 0; i--) {
      File file = (File)deleteFilesPool.get(i);
      file.delete();
      if (!file.exists())
        deleteFilesPool.remove(i);
    }
    try
    {
      ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(POOL_FILE));

      out.writeObject(deleteFilesPool);
      out.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static File getUniqueFile(Class cl, String extension)
  {
    int key = cl.getResource(getClassNameWithoutPackage(cl) + ".class").hashCode();

    File propFile = new File(System.getProperty("java.io.tmpdir"), getClassNameWithoutPackage(cl) + key + extension);

    return propFile;
  }

  private static String getClassNameWithoutPackage(Class cl) {
    String className = cl.getName();
    int pos = className.lastIndexOf('.') + 1;
    if (pos == -1)
      pos = 0;
    String name = className.substring(pos);
    return name;
  }

  static
  {
    try
    {
      initPool();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
